/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package api;

import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;
import java.io.*;
import java.util.Date;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

/**
 * REST Web Service
 *
 * @author TanPV
 */
@Path("tesseract")
public class Tesseract {

    @Context
    private UriInfo context;
    
    
    @Context
    private ServletContext servletContext;

    /**
     * Creates a new instance of Tesseract
     */
    public Tesseract() {
    }

    /**
     * Retrieves representation of an instance of api.Tesseract
     * @return an instance of java.lang.String
     */
    @GET
    @Produces("application/json")
    public String getJson() {
        //TODO return proper representation object
        //khong ho tro GET
           throw new UnsupportedOperationException();
    }

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public String postJson( @FormDataParam("image") InputStream uploadedInputStream,
                            @FormDataParam("image") FormDataContentDisposition fileDetail,
                            @DefaultValue("eng")    @FormDataParam("lang")        String lang,
                            @DefaultValue("3")      @FormDataParam("pagesegmode") String pagesegmode){
        /*
         * pagesegmode values are:
         * 0 = Orientation and script detection (OSD) only.
         * 1 = Automatic page segmentation with OSD.
         * 2 = Automatic page segmentation, but no OSD, or OCR
         * 3 = Fully automatic page segmentation, but no OSD. (Default)
         * 4 = Assume a single column of text of variable sizes.
         * 5 = Assume a single uniform block of vertically aligned text.
         * 6 = Assume a single uniform block of text.
         * 7 = Treat the image as a single text line.
         * 8 = Treat the image as a single word.
         * 9 = Treat the image as a single word in a circle.
         * 10 = Treat the image as a single character.
        */
        
        //duong dan den thu muc web
        String pathContext = servletContext.getRealPath("");
        
        //tao ten file ngau nhien
        String fileName = new StringBuilder().append("temp_")
                                             .append(new Date().getTime())
                                             .append(UUID.randomUUID()).toString();
        
                
        //duong dan luu file image va txt
        String pathInputFile = pathContext + "/" + fileName;
        String pathOuputFile = pathContext + "/" + fileName;
        String pathTextFile  = pathOuputFile + ".txt";
        
        //result
        JSONObject jsonResult = new JSONObject();
        
        
        writeToFile(uploadedInputStream, pathInputFile);
        
        //command
        String cmd  = "tesseract " + pathInputFile + " " + pathOuputFile + " -l " + lang + " -psm " + pagesegmode;
        Runtime run = Runtime.getRuntime();
        Process pr  = null;
        
        try {
            pr = run.exec(cmd);
            pr.waitFor();
        } catch (Exception e) {
            //xoa input file 
            File inputFile = new File(pathInputFile);
            inputFile.delete();
            
            try {
                jsonResult.put("error", true);
                jsonResult.put("message", "Cannot run tesseract command on the server");
            } catch (JSONException ex) {
                Logger.getLogger(Tesseract.class.getName()).log(Level.SEVERE, null, ex);
            } 
            return jsonResult.toString();
        }
        
        //xoa input file 
        File inputFile = new File(pathInputFile);
        inputFile.delete();
            
        
        //check output file exist
        File outputFile = new File(pathTextFile);
        // ouput file not found
        if(! outputFile.exists()) {
            // read output command
            BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream()));
            String line = "";
            String resp = "";
            try {
                while ((line=buf.readLine())!=null) {
                    line += " ";    
                    resp += line; 
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            
            try {
                jsonResult.put("error", true);
                jsonResult.put("message", resp);
            } catch (JSONException ex) {
                Logger.getLogger(Tesseract.class.getName()).log(Level.SEVERE, null, ex);
            } 
            return jsonResult.toString();
 
        }
        
        
        try {
                jsonResult.put("error", false);
                jsonResult.put("message", readFile(pathTextFile));
            } catch (JSONException ex) {
                Logger.getLogger(Tesseract.class.getName()).log(Level.SEVERE, null, ex);
            } 
        
        //xoa output File
        outputFile.delete();
        
        return jsonResult.toString();
    }
    
    
        	// save uploaded file to new location
	private void writeToFile(InputStream uploadedInputStream,String uploadedFileLocation) {
 
		try {
			OutputStream out = new FileOutputStream(new File(
					uploadedFileLocation));
			int read = 0;
			byte[] bytes = new byte[1024];
 
			out = new FileOutputStream(new File(uploadedFileLocation));
			while ((read = uploadedInputStream.read(bytes)) != -1) {
				out.write(bytes, 0, read);
			}
			out.flush();
			out.close();
		} catch (IOException e) {
 
			e.printStackTrace();
		}
        }
        
        private String readFile(String fileName) {
            
            String content = "";
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName),"UTF-8"));
                String eol = System.getProperty("line.separator");
                String strLine;
                while ((strLine = br.readLine()) != null) { 
                    content = content + strLine + eol;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        
            return content;
        }
 
    
}